/*************************************
* @update: 2021-04-20  liLinBin  [添加部分配置文件,同时将port, proxy提出到单独的my.config.js配置中]
* @update: 2021-04-26  liLinBin  [增加图片的js读取,增加全局less变量文件]
* @update: 2021-05-27  liLinBin  [增加'deleteConsole'等配置]
* @update: 2021-07-15  liLinBin  [更改生产的静态资源]
* @update: 2021-08-17  liLinBin  [按需加载项目]
* @update: 2021-08-19  liLinBin  [按需打包项目图片]
* @update: 2021-08-19  liLinBin  [按需build项目]
* 
* @description: vue-cli4 配置文件
****************************************/

const path = require('path')
const webpack = require('webpack')

const antdLessVars = require('./antd.less.vars')
const { NODE_ENV } = process.env
const BUILD = (process.env.BUILD || '').trim()

const {
    baseConfig,
    proxyConfig,
    buildProjects,
    externals,
    buildInfo
} = require('./my.config')

const cesiumSourcePath = "../ProjectFrame/projects/vcloud-cesium/node_modules/cesium/Source"





module.exports = {
    runtimeCompiler: true,      // 是否使用包含运行时编译器的Vue构建版本
    // filenameHashing: false,  // 去掉文件名中的 hash
    lintOnSave: false,          // 关闭eslint检查
    publicPath: "/",            // 默认根路径
    assetsDir: "",              // 默认
    productionSourceMap: false, //去除打包后js的map文件
    devServer: {
        open: true,
        host: '0.0.0.0',
        port: baseConfig.port || 'auto',
        hot: true,              //or hotOnly: true
        overlay: { warnings: false, errors: false },
        proxy: Object.keys(proxyConfig || {}).length !== 0 ? proxyConfig : ''
    },

    outputDir: BUILD === "buildComp" || BUILD === "autoBuildComp"
        ? baseConfig.buildCompDir.includes("/components/")
            ? `${baseConfig.buildCompDir}${buildProjects[0]}`
            : baseConfig.buildCompDir
        : './dist',

    //修改ant-design-vue的默认主题
    css: {
        // extract: true, //将组件内的css提取到一个单独的css文件
        sourceMap: NODE_ENV === 'development' ? true : false,
        // modules: false,  //为所有的css及预处理文件开启css Modules
        loaderOptions: {
            less: {
                lessOptions: {
                    modifyVars: antdLessVars,
                    javascriptEnabled: true
                }
            }
        }
    },

    configureWebpack (config) {
        let extObj = {}

        if (BUILD === "buildComp" || BUILD === "autoBuildComp") {
            extObj = getCommonRequire()
        }

        return {
            externals: { ...extObj, ...externals },   //合并
            plugins: [
                //去掉moment.js 除zh-cn 以外的语言包
                new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/),

                //cesium的静态资源
                new webpack.DefinePlugin({
                    CESIUM_BASE_URL: JSON.stringify('./ProjectFrame/projects/vcloud-cesium/cesium')
                })
            ],
            module: {
                //解决Ctritical dependency: require function is used in a way...的问题
                unknownContextCritical: false,

                //解决the request of a dependency is an expression
                exprContextCritical: false,
            }
        }
    },
    chainWebpack: (config) => {
        // config.resolve.symlinks(true) //解决vue-cli脚手架热更新失效

        const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
        types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)))

        //路径别名
        setAlias(config)
        //去掉'production'环境下的console
        deleteConsole(config)
        addConst(config)
        copySource(config)
    }
}



//路径别名
function setAlias (config) {
    //平台的路径别名,简化开发时的路径拼写
    config.resolve.alias
        .set('@', resolve('src'))
        .set('assets', resolve('src/assets'))
        .set('components', resolve('src/components'))
        .set('router', resolve('src/router'))
        .set('system', resolve('src/system'))
        .set('tools', resolve('src/tools'))

    //项目开发时工具的路径别名,简化开发时的路径拼写
    config.resolve.alias
        .set('projects', resolve('../ProjectFrame/projects'))
        .set('pCommon', resolve('../ProjectFrame/pCommon'))
        .set('pTools', resolve('../ProjectFrame/pTools'))
        .set('cesium', path.resolve(__dirname, cesiumSourcePath))
}



function resolve (dir) {
    return path.join(__dirname, dir)
}



function addStyleResource (rule) {
    rule.use('style-resource')
        .loader('style-resources-loader')
        .options({
            patterns: [
                path.resolve(__dirname, './src/assets/css/common_variable.less'),
                path.resolve(__dirname, '../ProjectFrame/projects/vcloud-cesium/assets/css/common.less')
            ]
        })
}



//去掉'production'环境下的console
function deleteConsole (config) {
    if (NODE_ENV === "production" && BUILD !== "buildOther") {
        config.optimization
            .minimize(true)
            .minimizer('terser')
            .tap(args => {
                let { terserOptions } = args[0];
                terserOptions.compress.drop_console = true;
                terserOptions.compress.drop_debugger = true;
                return args
            });
    }
}


function addConst (config) {
    config.plugin('define').tap(args => {
        args[0]['process.env'].buildProjects = JSON.stringify(buildProjects)
        args[0]['process.env'].baseConfig = JSON.stringify(baseConfig)
        args[0]['process.env'].buildInfo = JSON.stringify(buildInfo)
        args[0]['process.env'].isVTools = true
        return args
    })
}


function copySource (config) {
    if (BUILD === "buildOther") return

    //VTools本身的资源
    const platformSource = [
        {
            from: './public/images',
            to: 'images',
            info: { minimized: true },
            noErrorOnMissing: false
        },
        {
            from: 'onlineConfig.js',
            to: '',
            info: { minimized: true },
            noErrorOnMissing: false
        }
    ]

    const toPath = BUILD === "buildComp" || BUILD === "autoBuildComp"
        ? '../../ProjectFrame'
        : './ProjectFrame'

    //当前编译的项目的资源
    let projectSource = buildProjects.map(prjName => ({
        from: path.resolve(__dirname, `../ProjectFrame/projects/${prjName}/**/*`),
        to: toPath,   //相对outputDir的路径
        globOptions: {
            dot: true,
            gitignore: true,
            ignore: [
                "**/node_modules/**",
                "**/*.vue",
                "**/*.js",
                "**/*.css",
                "**/*.txt",
                "**/*.db",
                "**/font-family/**",
                "**/package.json",
                "**/package-lock.json",
                "**/.git/**",
                "**/.gitignore",
                "**/.svn",
                "**/prj-示范项目目录/**",
                "**/prj.config.json"
            ]
        },
        info: { minimized: true },
        noErrorOnMissing: false
    }))

    //cesium的资源
    const cesiumSource = [
        {
            from: path.join(cesiumSourcePath, '../Build/Cesium/Workers'),
            to: toPath + '/projects/vcloud-cesium/cesium/Workers',
            info: { minimized: true },
            noErrorOnMissing: false
        },
        {
            from: path.join(cesiumSourcePath, 'Assets'),
            to: toPath + '/projects/vcloud-cesium/cesium/Assets',
            info: { minimized: true },
            noErrorOnMissing: false
        },
        {
            from: path.join(cesiumSourcePath, 'Widgets'),
            to: toPath + '/projects/vcloud-cesium/cesium/Widgets',
            info: { minimized: true },
            noErrorOnMissing: false
        },
        {
            from: path.join(cesiumSourcePath, 'ThirdParty/Workers'),
            to: toPath + '/projects/vcloud-cesium/cesium/ThirdParty/Workers',
            info: { minimized: true },
            noErrorOnMissing: false
        }
    ]

    //富文本的资源
    const UEditorSource = [
        {
            from: path.resolve(__dirname, `../ProjectFrame/projects/富文本/UEditor`),
            to: toPath + '/projects/富文本/UEditor',
            info: { minimized: true },
            noErrorOnMissing: false
        }
    ]

    buildProjects.includes("vcloud-cesium") && projectSource.push(...cesiumSource)
    buildProjects.includes("富文本") && projectSource.push(...UEditorSource)

    let allSources = []

    switch (true) {
        case BUILD === "buildComp" || BUILD === "autoBuildComp":
            allSources = projectSource
            break;

        default:
            allSources = platformSource.concat(projectSource)
            break;
    }

    config.plugin('copy').use(require('copy-webpack-plugin'), [allSources])
}



function getCommonRequire () {
    return {
        //旧
        "assets/font/fontTypes": {
            commonjs: 'assets/font/fontTypes',
            commonjs2: 'assets/font/fontTypes',
            amd: 'assets/font/fontTypes'
        },
        "assets/font/fontTypes.js": {
            commonjs: 'assets/font/fontTypes',
            commonjs2: 'assets/font/fontTypes',
            amd: 'assets/font/fontTypes'
        },
        "tools/components/3_aUploadImg": {
            commonjs: 'tools/components/3_aUploadImg',
            commonjs2: 'tools/components/3_aUploadImg',
            amd: 'tools/components/3_aUploadImg'
        },
        "tools/components/3_aUploadImg.vue": {
            commonjs: 'tools/components/3_aUploadImg',
            commonjs2: 'tools/components/3_aUploadImg',
            amd: 'tools/components/3_aUploadImg'
        },
        "tools/components/6_vcloudColorPicker": {
            commonjs: 'tools/components/6_vcloudColorPicker',
            commonjs2: 'tools/components/6_vcloudColorPicker',
            amd: 'tools/components/6_vcloudColorPicker'
        },
        "tools/components/6_vcloudColorPicker.vue": {
            commonjs: 'tools/components/6_vcloudColorPicker',
            commonjs2: 'tools/components/6_vcloudColorPicker',
            amd: 'tools/components/6_vcloudColorPicker'
        },

        /****************** 新 ******************/
        /* "assets/font/fontTypes": {
            commonjs: 'fontTypes',
            commonjs2: 'fontTypes',
            amd: 'fontTypes'
        },
        "assets/font/fontTypes.js": {
            commonjs: 'fontTypes',
            commonjs2: 'fontTypes',
            amd: 'fontTypes'
        },
        "assets/font/fontWeightOption": {
            commonjs: 'fontWeight',
            commonjs2: 'fontWeight',
            amd: 'fontWeight'
        },
        "assets/font/fontWeightOption.js": {
            commonjs: 'fontWeight',
            commonjs2: 'fontWeight',
            amd: 'fontWeight'
        },
        "tools/components/3_aUploadImg": {
            commonjs: 'aUploadImg',
            commonjs2: 'aUploadImg',
            amd: 'aUploadImg'
        },
        "tools/components/3_aUploadImg.vue": {
            commonjs: 'aUploadImg',
            commonjs2: 'aUploadImg',
            amd: 'aUploadImg'
        },
        "tools/components/6_vcloudColorPicker": {
            commonjs: 'vcloudColorPicker',
            commonjs2: 'vcloudColorPicker',
            amd: 'vcloudColorPicker'
        },
        "tools/components/6_vcloudColorPicker.vue": {
            commonjs: 'vcloudColorPicker',
            commonjs2: 'vcloudColorPicker',
            amd: 'vcloudColorPicker'
        },
        "tools/mixins/2_eventConfigMixin.umd.min": {
            commonjs: 'eventConfigMixin',
            commonjs2: 'eventConfigMixin',
            amd: 'eventConfigMixin'
        },
        "tools/mixins/4_changeDataConfigMixin": {
            commonjs: 'changeDataConfigMixin',
            commonjs2: 'changeDataConfigMixin',
            amd: 'changeDataConfigMixin'
        }, */
        "tools/utils/3_pageTool": {
            commonjs: 'tools/utils/3_pageTool',
            commonjs2: 'tools/utils/3_pageTool',
            amd: 'tools/utils/3_pageTool'
        },
        "projects/common/mixin/interactMixin": {
            commonjs: 'interactMixin',
            commonjs2: 'interactMixin',
            amd: 'interactMixin'
        }
        /****************** 新 ******************/
    }
}



function imageLoader (config) {
    config.module
        .rule("images")
        .use("image-webpack-loader")
        .loader("image-webpack-loader")
        .options({
            mozjpeg: { progressive: true, quality: 65 },
            optipng: { enabled: false },
            pngquant: { quality: [0.65, 0.9], speed: 4 },
            gifsicle: { interlaced: false }
            // webp: { quality: 75 }
        })
}







// "lib": "vue-cli-service build --mode production --target lib --formats=umd-min --name index --dest public/buildComp src/components/index.js"
